package com.ys.day31.p4Gson;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ys.day31.p3FastJson.Student;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * 描述:
 * 扩展;
 * () 强制转换运算符
 * <> 钻石运算符，用于定义泛型
 * [] 数组运算符
 * {} 代码块
 *
 * @author CodeYang_Site
 * @version 2021/1/22 1:18
 */
public class P1Gson解析 {

    public static void main(String[] args) {
//        function01();
//
//        function02();
        function03();

    }

    private static void function03() {
        System.out.println("转换复杂的json_str -> Gson -> java obj");

        // 2 将 jsonstr 转为 java 对象
        try {
            Gson gson = new Gson();
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("day_31/etc/jsonArr.json")));
            StringBuilder jsonDataInReader = new StringBuilder();
            String len = null;
            while ((len = in.readLine()) != null) {
                jsonDataInReader.append(len);
            }


            //编译失败：GSON支持泛型但是不支持集合的泛型
            // List<Course> list = gson.fromJson(jsonData, Course.class);
            // 想一个办法，告诉GSON我需要返回什么类型的对象
            // 如何告诉GSON？我们把要返回的类型通过TypeToken告诉GSON
            // 创建TypeToken对象，该对象支持泛型，泛型里面的List<Course>就是我告诉GSON，需要返回的类型
            // Token翻译成中文“令牌”，此时表示：我的程序和GSON进行沟通的桥梁，我将需要返回的类新通过“令牌”带个GSON
            // 为什么 这里 是  new TypeToken<List<Student>>() { }; 有 {};
            TypeToken<List<Student>> typeToken = new TypeToken<List<Student>>() {
            };
            // token.getType() 获取令牌里面持有的类型
            // 准确的说token.getType()才是告诉GSON我要返回的数据类型

            List<Student> list = gson.fromJson(jsonDataInReader.toString(), typeToken.getType());
            for (Student student : list) {
                System.out.println(student);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void function02() {
        System.out.println("使用GSON将普通的Java对象转换为JSON对象");
        // 2 将 jsonstr 转为 java 对象
        try {
            Gson gson = new Gson();
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("day_31/etc/jsonObject.json")));
            StringBuilder jsonDataInReader = new StringBuilder();
            String len = null;
            while ((len = in.readLine()) != null) {
                jsonDataInReader.append(len);
            }
            //GSON提供了from开头的方法，将JSON对象转换为Java对象
            //
            //​	   不管是FASTJSON还是GSON，进行转换的时候我们定义的Java对象的属性名称一定要跟JSON属性名称一致否则无法获取数据
            //
            Student student = gson.fromJson(jsonDataInReader.toString(), Student.class);
            System.out.println(student);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    private static void function01() {
        System.out.println("普通Java obj -> Gson -> json_str");
        // 1 java obj -> Gson -> json str
        Worker worker = new Worker(101, "教师", 80000);
        Gson gson = new Gson();

        String json_str = gson.toJson(worker);
        System.out.println(json_str);
        //总结: Gson提供了to开头的方法，将Java对象转换为JSON对象
        // 1而且 与原生 Json 解析一样需要 new 对象来使用 成员方法, new JSON() | new Gson()
        // 2 alibaba fastJson 是静态方法 不需要new
    }
}
